# -*- coding: utf-8 -*-
from mitmproxy.options import Options
from mitmproxy.http import HTTPFlow
from mitmproxy.http import Response, Request, Headers

from mitmproxy.http import Headers as HTTP_Headers
from mitmproxy.net.server_spec import ServerSpec
from mitmproxy.addons.proxyserver import Proxyserver
from mitmproxy.tools.dump import DumpMaster
import asyncio
from AddonBase import AddonBase
from ZiMoooModule.TcpPullSeverClient import Server as TcpServer, MySocketEvent
import redis
import json
import os
import HPSocket.pyhpsocket as HPSocket
import base64
from mitmproxy.http import cookies as http_cookies

from handle_flow import flow_data_to_json, get_flow_process, get_cookie_expires
from ZiMoooModule.system import *
from ZiMoooModule.redis_install import auto_install_redis
from ZiMoooModule.compute import *

API_CODE_REQUEST = 11
API_CODE_RESPONSE = 12
API_CODE_SET_PROXY = 13
API_CODE_SET_INTERCEPT = 14
API_CODE_ADD_BW_PROCESS_INFO = 15

API_CODE_DEL_INTERCEPT = 16
API_CODE_DEL_PROXY = 17
API_CODE_CLEAR_INTERCEPT = 18
API_CODE_CLEAR_PROXY = 19
API_CODE_DEL_BW_PROCESS_INFO = 20

API_CODE_MODIFY_REQUEST_HEADERS = 1
API_CODE_MODIFY_REQUEST_COOKIES = 2
API_CODE_MODIFY_REQUEST_POSTDATA = 4
API_CODE_MODIFY_REQUEST_NEW = 8

API_CODE_MODIFY_RESPONSE_REDIRECTION = 1
API_CODE_MODIFY_RESPONSE_DATA = 2
API_CODE_MODIFY_RESPONSE_COOKIES = 4


class MyProxyList():
    def __init__(self):
        pass

    def add_proxy(self, ConnID, proxy, bwid=None, name=None):
        global redis_poll
        proxy_list = self.get_proxy()
        data = {"ConnID": ConnID, "name": name, "bwid": bwid, "proxy": proxy}
        if not any(data == d for d in proxy_list):
            proxy_list.append(data)
            r = redis.Redis(connection_pool=redis_poll)
            r.set(name="proxy_list", value=json.dumps(proxy_list))
        return proxy_list

    def clear(self):
        global redis_poll
        r = redis.Redis(connection_pool=redis_poll)
        r.delete("proxy_list")

    def del_proxy(self, ConnID=None, bwid=None, name=None):
        global redis_poll
        _list = self.get_proxy()
        n_list = []
        if ConnID is not None:
            for item in _list:
                if not (item["ConnID"] == ConnID):
                    n_list.append(item)
        else:
            if bwid is not None:
                for item in _list:
                    if not (item["bwid"] == bwid):
                        n_list.append(item)
            else:
                for item in _list:
                    if not (item["name"].upper() == name.upper()):
                        n_list.append(item)
        r = redis.Redis(connection_pool=redis_poll)
        r.set(name="proxy_list", value=json.dumps(n_list))
        return n_list

    def get_proxy(self):
        global redis_poll
        r = redis.Redis(connection_pool=redis_poll)
        if r.exists("proxy_list"):
            proxy_list = r.get("proxy_list")
            proxy_list = json.loads(proxy_list)
        else:
            proxy_list = []
        return proxy_list

    def is_use_proxy(self, bwid, name):
        proxy_list = self.get_proxy()
        if not proxy_list:
            return None
        else:
            for item in proxy_list:
                if item["bwid"] is not None:
                    if item["bwid"] == bwid:
                        return item["proxy"]
                elif item["name"].upper() == name.upper():
                    return item["proxy"]
            return None


class MyIntercept():
    def __init__(self):
        pass

    def add_intercept(self, ConnID, url="*", bwid=None, name=None, method="*", onlyreponse=False,
                      onlyRead=True):
        global redis_poll
        intercept_list = self.get_intercept()
        new_list = []
        if url == "*":
            for itc in intercept_list:
                if not (itc["bwid"] == bwid and itc["name"].upper() == name.upper()):
                    new_list.append(itc)
        else:
            for itc in intercept_list:
                if not (url == itc["url"] and itc["bwid"] == bwid and itc["name"].upper() == name.upper()):
                    new_list.append(itc)
        new_list.append({"ConnID": ConnID,
                         "bwid": bwid,
                         "name": name,
                         "url": url,
                         "method": method,
                         "onlyreponse": onlyreponse,
                         "onlyRead": onlyRead})
        r = redis.Redis(connection_pool=redis_poll)
        r.set(name="intercept_list", value=json.dumps(new_list))
        return new_list

    def del_intercept(self, ConnID=None, bwid=None, name=None, url=None):
        global redis_poll
        _list = self.get_intercept()
        n_list = []
        for item in _list:
            if ConnID is not None:
                if not (item["ConnID"] == ConnID):
                    n_list.append(item)
            else:
                if url is not None and bwid is not None:
                    if not (item["bwid"] == bwid and item["url"] == url):
                        n_list.append(item)
                elif url is not None and name is not None:
                    if not (item["name"].upper() == name.upper() and item["url"] == url):
                        n_list.append(item)

                elif bwid is not None:
                    if not (item["bwid"] == bwid):
                        n_list.append(item)
                else:
                    if not (item["name"].upper() == name.upper()):
                        n_list.append(item)

        r = redis.Redis(connection_pool=redis_poll)
        r.set(name="intercept_list", value=json.dumps(n_list))
        return n_list

    def clear(self):
        global redis_poll
        r = redis.Redis(connection_pool=redis_poll)
        r.delete("intercept_list")

    def get_intercept(self):
        global redis_poll
        r = redis.Redis(connection_pool=redis_poll)
        if r.exists("intercept_list"):
            intercept_list = r.get("intercept_list")
            return json.loads(intercept_list)
        else:
            print("intercept_list no exists")
            return []

    def is_use_intercept(self, url: str, method: str, isRequest: bool, bwid: int, name: str):
        intercept_list = self.get_intercept()
        if not intercept_list:
            return None
        else:
            for item in intercept_list:
                if item["bwid"] is not None:
                    if bwid == item["bwid"]:
                        if item["url"] == "*" or item["url"] in url:
                            if item["method"] == "*" or method.upper() == item["method"].upper():
                                if item["onlyreponse"] == False or isRequest == False:
                                    return item["onlyRead"]

                elif name.upper() == item["name"].upper():
                    if item["url"] == "*" or item["url"] in url:
                        if item["method"] == "*" or method.upper() == item["method"].upper():
                            if item["onlyreponse"] == False or isRequest == False:
                                return item["onlyRead"]
            return None


class MyConnection():
    def __init__(self):
        pass

    def add_connection(self, ConnID: int, bwid: int = None, name: str = None):
        global redis_poll
        _list = self.get_connection_list()
        data = {"ConnID": ConnID, "bwid": bwid, "name": name}
        if not any(data == d for d in _list):
            _list.append(data)
            r = redis.Redis(connection_pool=redis_poll)
            r.set(name="connection_list", value=json.dumps(_list))
        return _list

    def del_connection(self, ConnID=None, bwid=None, name=None):
        global redis_poll
        _list = self.get_connection_list()
        n_list = []
        for item in _list:
            if bwid is not None:
                if not (item["bwid"] == bwid):
                    n_list.append(item)
            elif name is not None:
                if not (item["name"].upper() == name.upper()):
                    n_list.append(item)
            else:
                if not (item["ConnID"] == ConnID):
                    n_list.append(item)
        r = redis.Redis(connection_pool=redis_poll)
        r.set(name="connection_list", value=json.dumps(n_list))
        return n_list

    def clear(self):
        global redis_poll
        r = redis.Redis(connection_pool=redis_poll)
        r.delete("connection_list")

    def get_connection_list(self):
        global redis_poll
        r = redis.Redis(connection_pool=redis_poll)
        if r.exists("connection_list"):
            intercept_list = r.get("connection_list")
            intercept_list = json.loads(intercept_list)
            return intercept_list
        else:
            return []

    def getConnID(self, bwid: int, name: str):
        _list = self.get_connection_list()
        for item in _list:
            if item["bwid"] is not None:
                if item["bwid"] == bwid:
                    return item["ConnID"]
            elif name.upper() == item["name"].upper():
                return item["ConnID"]
        return 0


class HPEVENT(MySocketEvent):
    def __init__(self, parent):
        super().__init__(parent=parent)
        self.MyConnection = MyConnection()
        self.MyProxyList = MyProxyList()
        self.MyIntercept = MyIntercept()

        self.MyProxyList.clear()
        self.MyIntercept.clear()
        self.MyConnection.clear()

    def OnReceive(self, data, flag, ApiCode, ConnID):
        '''
        数据到达
        :param data: 数据
        :param flag: 标识
        :param ApiCode: APICODE
        :param ConnID: 连接ID 若是客户端 此参数为None
        :return:
        '''
        print("数据到达", ConnID, flag, ApiCode, data)
        return HPSocket.EnHandleResult.HR_OK

    def OnRequest(self, data, flag, ApiCode, ConnID):
        '''
        请求到达
        :param data: 数据
        :param flag: 标识
        :param ApiCode: APICODE
        :param ConnID: 连接ID 若是客户端 此参数为None
        :return:
        '''
        print("请求到达", ConnID, flag, ApiCode, data)
        msg = {}
        data = json.loads(data)
        # 添加浏览器进程信息
        if ApiCode == API_CODE_ADD_BW_PROCESS_INFO:
            try:
                connect_list = self.MyConnection.add_connection(ConnID=ConnID, bwid=data.get("bwid", None),
                                                                name=data.get("name", None))
                msg = {"code": 200, "msg": "success", "data": connect_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】保存进程信息异常：{E}"}

        if ApiCode == API_CODE_DEL_BW_PROCESS_INFO:
            try:
                intercept_list = self.MyConnection.del_connection(ConnID=ConnID,
                                                                  bwid=data.get("bwid", None),
                                                                  name=data.get("name", None))
                msg = {"code": 200, "msg": "success", "data": intercept_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】删除进程信息异常：{E}"}

        if ApiCode == API_CODE_SET_PROXY:
            try:
                proxy_list = self.MyProxyList.add_proxy(ConnID=ConnID,
                                                        bwid=data.get("bwid", None),
                                                        name=data.get("name", None),
                                                        proxy=data["proxy"]
                                                        )
                msg = {"code": 200, "msg": "success", "data": proxy_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】保存代理信息异常：{E}"}

        if ApiCode == API_CODE_SET_INTERCEPT:
            try:
                intercept_list = self.MyIntercept.add_intercept(ConnID=ConnID,
                                                                bwid=data.get("bwid",None),
                                                                name=data.get("name",None),
                                                                url=data.get("url","*"),
                                                                method=data.get("method","*"),
                                                                onlyreponse=data.get("onlyreponse", False),
                                                                onlyRead=data.get("onlyRead", True))
                msg = {"code": 200, "msg": "success", "data": intercept_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】保存拦截信息异常：{E}"}

        if ApiCode == API_CODE_DEL_PROXY:
            try:
                proxy_list = self.MyProxyList.del_proxy(bwid=data.get("bwid", None),
                                                        name=data.get("name", None))
                msg = {"code": 200, "msg": "success", "data": proxy_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】删除代理信息异常：{E}"}

        if ApiCode == API_CODE_CLEAR_PROXY:
            try:
                proxy_list = self.MyProxyList.del_proxy(ConnID=ConnID)
                msg = {"code": 200, "msg": "success", "data": proxy_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】清空代理信息异常：{E}"}

        if ApiCode == API_CODE_DEL_INTERCEPT:
            try:
                intercept_list = self.MyIntercept.del_intercept(bwid=data.get("bwid", None),
                                                                url=data.get("url", None),
                                                                name=data.get("name", None))
                msg = {"code": 200, "msg": "success", "data": intercept_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】删除拦截信息异常：{E}"}
            pass
        if ApiCode == API_CODE_CLEAR_INTERCEPT:
            try:
                intercept_list = self.MyIntercept.del_intercept(ConnID=ConnID)
                msg = {"code": 200, "msg": "success", "data": intercept_list}
            except Exception as E:
                msg = {"code": 201, "msg": f"连接【{ConnID}】清空拦截信息异常：{E}"}

        msg = json.dumps(msg)
        print("回复msg", msg)
        print("回复", self.parent.Answer(ConnID=ConnID, flag=flag, apiCode=ApiCode, data=msg.encode()))
        return HPSocket.EnHandleResult.HR_OK

    def OnClose(self, Sender, ConnID, Operation, ErrorCode):
        '''
        连接断开
        :param ConnID:
        :param ErrorCode:
        :return:
        '''
        print("连接断开", Sender, ConnID, Operation, ErrorCode)
        try:
            self.MyProxyList.del_proxy(ConnID=ConnID)
            self.MyIntercept.del_intercept(ConnID=ConnID)
            self.MyConnection.del_connection(ConnID=ConnID)
        except Exception as E:
            print(f"清空连接【{ConnID}】缓存信息异常：{E}")
        return HPSocket.EnHandleResult.HR_OK

    def OnConnect(self, Sender, ConnID):
        '''
        客户进入
        :param Sender:
        :param ConnID:
        :return:
        '''
        print("连接成功", Sender, ConnID)
        return HPSocket.EnHandleResult.HR_OK

    def OnShutdown(self, Sender):
        '''
        服务器关闭
        :param Sender:
        :return:
        '''
        print("服务器关闭", Sender)
        try:
            self.MyProxyList.clear()
            self.MyIntercept.clear()
            self.MyConnection.clear()
        except Exception as E:
            print(f"清空缓存信息异常：{E}")
        return HPSocket.EnHandleResult.HR_OK


class InterceptHandle():
    def Request(self, flow: HTTPFlow):
        return flow

    def Reponse(self, flow: HTTPFlow):
        return flow


class MyAddon(AddonBase):
    def __init__(self, intercept=InterceptHandle):
        super().__init__()
        self.myintercept = MyIntercept()
        self.myproxy = MyProxyList()
        self.intercept = intercept()
        self.myConnection = MyConnection()

    def request(self, flow: HTTPFlow):

        process_info = get_flow_process(flow)
        if process_info:
            onlyRead = self.myintercept.is_use_intercept(url=flow.request.url,
                                                         method=flow.request.method,
                                                         isRequest=False,
                                                         bwid=process_info["ppid"],
                                                         name=process_info["name"])

        else:
            onlyRead = None


        if onlyRead is not None:
            flow = self.intercept.Request(flow=flow)
            flowdata = flow_data_to_json(flow=flow)
            flowdata["process"] = process_info
            ConnID = self.myConnection.getConnID(bwid=process_info["ppid"], name=process_info["name"])
            if ConnID > 0:
                if onlyRead == True:
                    tcp_server.SendData(ConnID=ConnID,
                                        apiCode=API_CODE_REQUEST,
                                        data=json.dumps(flowdata).encode())
                else:
                    response = tcp_server.Sync_SendData(ConnID=ConnID,
                                                        apiCode=API_CODE_REQUEST,
                                                        data=json.dumps(flowdata).encode(),
                                                        outTime=3)
                    if response:
                        response = response.decode()
                        print("请求处理返回：", response)
                        if bit_is_option_set(response["ModifyType"], API_CODE_MODIFY_REQUEST_COOKIES):
                            flow.request.cookies.clear()
                            for ck in response["cookies"]:
                                flow.request.cookies.add(key=ck["name"], value=ck["value"])
                            pass

                        if bit_is_option_set(response["ModifyType"], API_CODE_MODIFY_REQUEST_HEADERS):
                            flow.request.headers.clear()
                            for hd in response["headers"]:
                                flow.request.headers.add(key=hd["name"], value=hd["value"])
                            pass

                        if bit_is_option_set(response["ModifyType"], API_CODE_MODIFY_REQUEST_POSTDATA):
                            if response["data_type"] == 1:
                                flow.request.content = base64.b64decode(response["data"]).decode()
                            else:
                                flow.request.content = base64.b64decode(response["data"])
                            pass

                        if bit_is_option_set(response["ModifyType"], API_CODE_MODIFY_REQUEST_NEW):
                            headers = HTTP_Headers()
                            headers.clear()
                            for h in response["headers"]:
                                headers.add(key=h["name"], value=h["value"])

                            if response["data_type"] == 1:
                                response["data"] = base64.b64decode(response["data"]).decode()
                            else:
                                response["data"] = base64.b64decode(response["data"])
                            flow.request = Request.make(method=response["method"],
                                                        url=response["url"],
                                                        content=response["data"],
                                                        headers=headers)
                            pass

                        # def make(
                        #         cls,
                        #         method: str,
                        #         url: str,
                        #         content: Union[bytes, str] = "",
                        #         headers: Union[
                        #             Headers,
                        #             dict[Union[str, bytes], Union[str, bytes]],
                        #             Iterable[tuple[bytes, bytes]],
                        #         ] = (),
                        # ) -> "Request":
            else:
                print("接收进程已关闭或连接已断开...")
        if process_info:
            proxy_info = self.myproxy.is_use_proxy(bwid=process_info["ppid"], name=process_info["name"])
            if proxy_info:
                self.SetProxy(flow=flow,
                              proxy_host=proxy_info["host"],
                              proxy_port=proxy_info["port"],
                              proxy_type=proxy_info["type"],
                              username=proxy_info["username"],
                              password=proxy_info["password"])
            else:
                self.CanelProxy(flow)
        else:
            self.CanelProxy(flow)


    def response(self, flow: HTTPFlow):
        process_info = get_flow_process(flow)
        if process_info:
            onlyRead = self.myintercept.is_use_intercept(url=flow.request.url,
                                                         method=flow.request.method,
                                                         isRequest=False,
                                                         bwid=process_info["ppid"],
                                                         name=process_info["name"])
        else:
            onlyRead = None
        if onlyRead is not None:
            flowdata = flow_data_to_json(flow=flow)
            flowdata["process"] = process_info
            ConnID = self.myConnection.getConnID(bwid=process_info["ppid"],name=process_info["ppname"])
            if ConnID > 0:
                if onlyRead == True:
                    tcp_server.SendData(ConnID=ConnID,
                                        apiCode=API_CODE_RESPONSE,
                                        data=json.dumps(flowdata).encode())
                else:
                    response = tcp_server.Sync_SendData(ConnID=ConnID,
                                                        apiCode=API_CODE_RESPONSE,
                                                        data=json.dumps(flowdata).encode(),
                                                        outTime=3)
                    if response:
                        response = response.decode()
                        print("响应处理返回：", response)
                        if bit_is_option_set(response["ModifyType"], API_CODE_MODIFY_RESPONSE_DATA):
                            flow.response = Response.make(
                                status_code=200,
                                content=base64.b64decode(response["content"]),
                                headers=flow.response.headers
                            )

                        if bit_is_option_set(response["ModifyType"], API_CODE_MODIFY_RESPONSE_COOKIES):
                            flow.response.cookies.clear()
                            for ck in response["cookies"]:
                                ckas = http_cookies.CookieAttrs()
                                ckas.add("domain", ck["domain"])
                                MaxAge = 365 * 24 * 60 * 60
                                ckas.add("expires", get_cookie_expires(timeStamp=time.time(), MaxAge=MaxAge))
                                ckas.add("Max-Age", str(MaxAge))
                                ckas.add("path", "/")
                                ckas.add("secure", "")
                                try:
                                    flow.response.cookies.add(ck["name"], (ck["value"], ckas))
                                except Exception as E:
                                    print(f"response cookies 设置异常：{E}")

                        if bit_is_option_set(response["ModifyType"], API_CODE_MODIFY_RESPONSE_REDIRECTION):
                            flow.response = Response.make(
                                302,  # 302 Found redirect status code
                                headers={"Location": response["Location"]}
                            )
                            pass
                        # def make(
                        #         cls,
                        #         status_code: int = 200,
                        #         content: Union[bytes, str] = b"",
                        #         headers: Union[
                        #             Headers, Mapping[str, Union[str, bytes]], Iterable[tuple[bytes, bytes]]
                        #         ] = (),
                        # ) -> "Response":
            else:
                print("接收进程已关闭或连接已断开...")
                # flow = self.intercept.Reponse(flow)




def ReadConfig():
    global config
    with open(".\\Config.json", "r", encoding="utf-8") as f:
        config = f.read()
        config = json.loads(config)


def StartRedis():
    global config
    if config["redis"]["port"] <= 0:
        config["redis"]["port"] = get_new_port()
    if not config["redis"]["servername"]:
        config["redis"]["servername"] = "Redis50141"
    if not config["redis"]["path"]:
        config["redis"]["path"] = ".\\Redis"
    if not config["redis"]["host"]:
        config["redis"]["host"] = "localhost"

    global redis_poll
    port = auto_install_redis(path=config["redis"]["path"], port=config["redis"]["port"],
                              servername=config["redis"]["servername"])

    if port > 0:
        config["redis"]["port"] = port
        redis_poll = redis.ConnectionPool(host=config["redis"]["host"],
                                          port=config["redis"]["port"],
                                          db=0)
    else:
        redis_poll = None
        print("Redis 服务启动失败...")


async def StartTcpServer():
    global config, tcp_server
    if config["tcp"]["port"] <= 0 or is_port_in_use(config["tcp"]["port"]):
        config["tcp"]["port"] = get_new_port()
    if config["tcp"]["host"] == "":
        config["tcp"]["host"] = "127.0.0.1"
    tcp_server = TcpServer(config["tcp"]["host"], config["tcp"]["port"], MyEvent=HPEVENT)
    tcp_server.Start()
    await asyncio.sleep(1)
    while tcp_server.onLine:
        await asyncio.sleep(0.1)
    print("async Tcp Server Stoped.")


def SetGlobalProxy():
    global config
    if config["mitmproxy"]["global_proxy"]:
        set_system_proxy(enable_proxy=True,
                         proxy_address=f'http://{config["mitmproxy"]["host"]}:{config["mitmproxy"]["port"]}')
    else:
        set_system_proxy(enable_proxy=False)


def SaveConfig():
    global config
    with open(".\\Config.json", "w", encoding="utf-8") as f:
        f.write(json.dumps(config))


async def auto_install_cert():
    user_home_dir = os.path.expanduser('~')
    filename = f"{user_home_dir}\\.mitmproxy\\mitmproxy-ca-cert.cer"
    if is_mitmproxy_cert_installed():
        print("Mitmproxy证书已安装")
        print("async install_mitmproxy_certificate completed.")
        return True
    else:
        print("Mitmproxy证书未安装")
        while True:
            if check_file_exists(filename):
                install_mitmproxy_certificate(filename)
                print("async install_mitmproxy_certificate completed.")
                return True
            else:
                await asyncio.sleep(0.1)


async def start_mitmproxy():
    # 初始设置代理模式 默认：regular
    # mode: Sequence[str] = ["upstream:http://localhost:7889"]
    # options = Options(listen_host='localhost', listen_port=8889, mode=mode)
    global config
    if config["mitmproxy"]["port"] <= 0 or is_port_in_use(config["mitmproxy"]["port"]):
        config["mitmproxy"]["port"] = get_new_port()
    options = Options(listen_host=config["mitmproxy"]["host"], listen_port=config["mitmproxy"]["port"])
    options.add_option("connection_strategy", str, "lazy", "")
    options.add_option("upstream_cert", bool, False, "")
    options.add_option("ssl_insecure", bool, True, "")
    # EventLog verbosity. Default: info  Choices: error, warn, info, alert, debug
    # 事件日志 默认为 info
    options.add_option("console_eventlog_verbosity", str, "error", "")
    # Log verbosity.. Default: info  Choices: error, warn, info, alert, debug
    options.add_option("termlog_verbosity", str, "error", "")
    # 替换代理模式
    # mode: Sequence[str] = ["upstream:http://localhost:7889"]
    # mode_option = {'mode': mode}
    # options.update(**mode_option)
    m = DumpMaster(options=options,
                   with_termlog=True,
                   with_dumper=False
                   )
    # dump.py 第18行写入文件
    # outfile = open(".\\log.log", mode='a', encoding="utf-8")
    m.server = Proxyserver()
    addons = MyAddon()
    m.addons.add(addons)
    SaveConfig()
    await m.run()


async def main():
    print("main start")
    task_tcp_server = asyncio.create_task(StartTcpServer())
    task_main = asyncio.create_task(start_mitmproxy())
    task_auto_install_cert = asyncio.create_task(auto_install_cert())

    print("task create complete")
    await task_tcp_server
    await task_main
    await task_auto_install_cert

    print("main end")


if __name__ == '__main__':
    ReadConfig()
    SetGlobalProxy()
    StartRedis()
    asyncio.run(main())

    # 注释掉 C:\soft\python39\Lib\site-packages\mitmproxy\addons\dumper.py
    # 244行 和 253行 输出的日志

    '''    pyinstaller pymitmdump\mitmdumpStartApi.py --distpath pymitmdumpstartdist --add-data "pymitmdump\mitmdump_executable;mitmdump_executable" --add-data "pymitmdump\mitmdumpUrlSaver.py;."
    pyinstaller pymitmdump\mitmdumpOtherApi.py --distpath pymitmdumpotherdist
    '''
